package top.ruanlitao.shortlink.project.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import top.ruanlitao.shortlink.project.common.factory.ShortLinkThreadFactory;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * 统一线程池管理 配置类
 */
@Configuration
@EnableAsync
public class ThreadPoolConfig implements AsyncConfigurer {

    /**
     * 项目通用线程池（IO）
     */
    public static final String LINK_GENERAL_EXECUTOR = "linkGeneralIOExecutor";

    /**
     * 调用 API 查询当前 IP 归属地 线程池
     */
    public static final String LINK_IP_PLACE_OF_ORIGIN_EXECUTOR = "linkIpPlaceOfOriginExecutor";

    @Bean(LINK_GENERAL_EXECUTOR)
    @Primary
    public ThreadPoolTaskExecutor linkGeneralIOExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
        executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
        // 使用的阻塞队列是 LinkedBlockingQueue，队列长度设置为 200
        executor.setQueueCapacity(200);
        executor.setThreadNamePrefix("link-io-executor-");
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 优雅停机
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 自定义线程工厂，复用线程工厂并增加自定义异常捕获处理器
        executor.setThreadFactory(new ShortLinkThreadFactory(executor));
        // 初始化线程工厂
        executor.initialize();
        return executor;
    }

    @Bean(LINK_IP_PLACE_OF_ORIGIN_EXECUTOR)
    public ThreadPoolTaskExecutor linkIpPlaceOfOriginExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(3);
        // 使用的阻塞队列是 LinkedBlockingQueue，队列长度设置为 200
        executor.setQueueCapacity(200);
        executor.setThreadNamePrefix("ip-place-of-origin-executor-");
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 优雅停机
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 自定义线程工厂，复用线程工厂并增加自定义异常捕获处理器
        executor.setThreadFactory(new ShortLinkThreadFactory(executor));
        // 初始化线程工厂
        executor.initialize();
        return executor;
    }
}